package bsc.war.handler;

import bsc.ejb.entity.ActionPlan;
import bsc.ejb.entity.ActionPlanPerson;
import bsc.ejb.entity.Attachment;
import bsc.ejb.entity.ColorimetrySettings;
import bsc.ejb.entity.Comparator;
import bsc.ejb.entity.ComparatorDimensionalCut;
import bsc.ejb.entity.DimensionMember;
import bsc.ejb.entity.DimensionalCut;
import bsc.ejb.entity.Note;
import bsc.ejb.entity.Person;
import bsc.ejb.entity.Pointer;
import bsc.ejb.metadata.Colorimetry;
import bsc.ejb.metadata.Comparation;
import bsc.ejb.metadata.Framework;
import bsc.war.delegate.DelegateBSC;
import bsc.war.factory.Factory;
import bsc.war.model.ActionPlanPojo;
import bsc.war.model.Score;
import bsc.war.service.ScoreCardUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

/**
 *
 * @author Memo
 */
public class DashboardPointer extends AbstractController {

    public DashboardPointer() {
    }

    @Override
    protected ModelAndView handleRequestInternal(
            HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        try {
            DelegateBSC delegate = (DelegateBSC) Factory.getBean("DelegateBSC");

            processRequestInternal(request, response, delegate);

        } catch (Exception e) {
            logger.error("Catched exception", e);
        }
        return new ModelAndView("dashboardPointer");
    }

    public static void processRequestInternal(HttpServletRequest request,
            HttpServletResponse response, DelegateBSC delegate) {



        Date startDate = null;
        Date endDate = null;

        //Find the scorecard
        Long idDimensionalCutScoreCard = Long.parseLong(request.getParameter("scoreCard"));
        DimensionalCut dimensionalCutScoreCard = delegate.findDimensionalCut(idDimensionalCutScoreCard);
        Pointer pointer = dimensionalCutScoreCard.getPointer();



        //Impresion de parametros


        //Get dats from calendars
        if (request.getParameter("startDate") != null && request.getParameter("endDate") != null) {
            Integer tmpDate[] = new Integer[3];
            StringTokenizer dateTokens = new StringTokenizer(request.getParameter("startDate"), "/");
            for (int i = 0; i < 3; i++) {
                tmpDate[i] = Integer.parseInt(dateTokens.nextToken());
            }

            Integer tmpDateFinal[] = new Integer[3];
            StringTokenizer dateTokensFinal = new StringTokenizer(request.getParameter("endDate"), "/");
            for (int i = 0; i < 3; i++) {
                tmpDateFinal[i] = Integer.parseInt(dateTokensFinal.nextToken());
            }

            startDate = ScoreCardUtils.generateDate(tmpDate[0], tmpDate[1], tmpDate[2]);
            endDate = ScoreCardUtils.generateDate(tmpDateFinal[0], tmpDateFinal[1], tmpDateFinal[2]);

        } else {

            startDate = ScoreCardUtils.generateMinimumDate(ScoreCardUtils.getSystemDate(request), 5 * ScoreCardUtils.checkFrecuency(dimensionalCutScoreCard));
            endDate = ScoreCardUtils.getSystemDate(request);
        }
        //Impresion de Fechas
        //System.out.println("Fecha inicio: " + startDate);
        //System.out.println("Fecha final: " + endDate);


        //Find the cuts of the pointer
        //List<DimensionalCut> dimensionalCuts = delegate.findDimensionalCut((Pointer) pointer);

        //List of DimensionalCut of the Dhasboard
        List<DimensionalCut> dimensionalCuts = new ArrayList<DimensionalCut>();
        dimensionalCuts.add(dimensionalCutScoreCard);


        List<DimensionalCut> rootDimensionalCuts = new ArrayList<DimensionalCut>();

        //Members of the cut
        Map<DimensionalCut, List<DimensionMember>> cutMembers = new HashMap<DimensionalCut, List<DimensionMember>>();
        //Members of members boolean
        Map<DimensionalCut, Map<DimensionMember, Boolean>> cutMembersSons = new HashMap<DimensionalCut, Map<DimensionMember, Boolean>>();

        //Members String of the Cut
        Map<DimensionalCut, String> cutMembersString = new HashMap<DimensionalCut, String>();

        for (DimensionalCut dimensionalCut : dimensionalCuts) {
            List<DimensionMember> dimensionMembers = delegate.findDimensionMember(dimensionalCut);


            cutMembers.put(dimensionalCut, dimensionMembers);
            cutMembersString.put(dimensionalCut, ScoreCardUtils.createMembersString(dimensionMembers));
            rootDimensionalCuts.add(dimensionalCut);
            //check if members have sons
            cutMembersSons.put(dimensionalCut, ScoreCardUtils.reviewMembersSons(dimensionMembers, delegate));

        }

        //Comparator of the pointer - Basado en los comparador que se estan utilizando
        //List<Comparator> comparators = delegate.findComparator(pointer);
        Framework framework = delegate.findFramework(Boolean.TRUE);
        Comparation comparation = ScoreCardUtils.getSystemComparation(request);
        List<Comparator> comparators = new ArrayList();
        comparators.add(delegate.findComparator(dimensionalCutScoreCard.getPointer(), delegate.findComparation(framework, Comparation.Type.REAL)));
        comparators.add(delegate.findComparator(dimensionalCutScoreCard.getPointer(), comparation));

        //ComparatorsDimensionalCut of the cut
        Map<DimensionalCut, List<ComparatorDimensionalCut>> dataComparators = new HashMap<DimensionalCut, List<ComparatorDimensionalCut>>();

        Map<DimensionalCut, List<Date>> dimensionalCutDates = new HashMap<DimensionalCut, List<Date>>();
        Map<DimensionalCut, Map<Date, List<ComparatorDimensionalCut>>> dimensionalCutDatesData = new HashMap<DimensionalCut, Map<Date, List<ComparatorDimensionalCut>>>();
        Map<DimensionalCut, Map<Date, Double>> pointerScores = new HashMap<DimensionalCut, Map<Date, Double>>();
        Map<DimensionalCut, Map<Date, String>> pointerColors = new HashMap<DimensionalCut, Map<Date, String>>();




        for (DimensionalCut dimensionalCut : rootDimensionalCuts) {

            //List<Date> dimensionalCutDate = delegate.findComparatorDimensionalCutDate(dimensionalCut);
            //List<Date> dimensionalCutDate = ScoreCardUtils.generateDates(ScoreCardUtils.getSystemDate(request));
            List<Date> dimensionalCutDate = ScoreCardUtils.generateDatesRange(startDate, endDate, dimensionalCutScoreCard);

            Map<Date, List<ComparatorDimensionalCut>> comparatorDimensionalCutData = new HashMap<Date, List<ComparatorDimensionalCut>>();
            Map<Date, Double> pointerScore = new HashMap<Date, Double>();
            Map<Date, String> pointerColor = new HashMap<Date, String>();

            for (Date date : dimensionalCutDate) {
                List<ComparatorDimensionalCut> comparatorDimensionalCuts = new ArrayList();
                for (Comparator comparator : comparators) {
                    //List<ComparatorDimensionalCut> comparatorDimensionalCuts = delegate.findComparatorDimensionalCut(dimensionalCut, date);
                    ComparatorDimensionalCut comparatorDimensionalCut = delegate.findComparatorDimensionalCut(comparator, dimensionalCut, date);
                    comparatorDimensionalCuts.add(comparatorDimensionalCut);
                }

                comparatorDimensionalCutData.put(date, comparatorDimensionalCuts);
                //Score of each date of the Total pointer
                
                Score score = ScoreCardUtils.calculateScore(delegate, comparation, dimensionalCutScoreCard, date, dimensionalCut);
               

                if (!score.isOutOfDate()) {
                    pointerScore.put(date, score.getScore());
                    Colorimetry colorimetry = delegate.findColorimetry(dimensionalCutScoreCard, score.getScore());
                    pointerColor.put(date, colorimetry == null ? "" : colorimetry.getColor());
                }

            }

            dimensionalCutDates.put(dimensionalCut, dimensionalCutDate);
            dimensionalCutDatesData.put(dimensionalCut, comparatorDimensionalCutData);
            //Score of each date of the cut of the pointer (TOTAL in this case)
            pointerScores.put(dimensionalCut, pointerScore);
            pointerColors.put(dimensionalCut, pointerColor);


            List<ComparatorDimensionalCut> comparatorDimensionalCuts = delegate.findComparatorDimensionalCut(dimensionalCut);
            dataComparators.put(dimensionalCut, comparatorDimensionalCuts);
        }

        //Se manda a llamar el método que genera las fechas
        //List<Date> rangeDates= ScoreCardUtils.generateDates(ScoreCardUtils.getSystemDate(request));
        List<Date> rangeDates = ScoreCardUtils.generateDatesRange(startDate, endDate, dimensionalCutScoreCard);

        List<Note> notes = delegate.findNote(dimensionalCutScoreCard);
        Map<Note, List<Attachment>> noteAttachments = new HashMap<Note, List<Attachment>>();
        for (Note note : notes) {
            List<Attachment> attachments = delegate.findAttachment(note);
            noteAttachments.put(note, attachments);
        }


        //Se sube la colorimetría

        List<ColorimetrySettings> colorimetries = delegate.findColorimetrySettings(dimensionalCutScoreCard);
        Map<ColorimetrySettings, Double> colorRangeMin = new HashMap<ColorimetrySettings, Double>();
        Map<ColorimetrySettings, Double> colorRangeMax = new HashMap<ColorimetrySettings, Double>();
        for (ColorimetrySettings colorimetrySettings : colorimetries) {
            Double maxScore = colorimetrySettings.getMaxScore();
            Double minScore = colorimetrySettings.getMinScore();

            colorRangeMax.put(colorimetrySettings, maxScore);
            colorRangeMin.put(colorimetrySettings, minScore);
        }

        //Update members of all dimensional cuts
        //List of all DimensionalCuts
        //List<DimensionalCut> dimensionalCutsPointer = ScoreCardUtils.getDimensionalCuts(request, delegate);
        List<DimensionalCut> dimensionalCutsPointer = new ArrayList<DimensionalCut>();
        dimensionalCutsPointer.add(dimensionalCutScoreCard);

        //Se obtiene los strings de los cuts
        java.util.Map<DimensionalCut, String> dimensionalCutsMembers = ScoreCardUtils.getDimensionalCutsMembersStrings(request, delegate, dimensionalCutsPointer);

        String pointerName = dimensionalCutScoreCard.getName() + " ( " + (String) dimensionalCutsMembers.get(dimensionalCutScoreCard) + " )";


        request.setAttribute("pointerName", pointerName);


        List<ActionPlanPojo> actionPlanPojos = ScoreCardUtils.getActionPlans(delegate, dimensionalCutScoreCard);

       



        request.setAttribute("pointer", dimensionalCutScoreCard);
        request.setAttribute("dimensionalCuts", dimensionalCuts);
        request.setAttribute("dimensionalCutsMembers", dimensionalCutsMembers);
        request.setAttribute("rootDimensionalCuts", rootDimensionalCuts);

        request.setAttribute("cutMembers", cutMembers);
        request.setAttribute("cutMembersSons", cutMembersSons);

        request.setAttribute("comparators", comparators);
        request.setAttribute("dataComparators", dataComparators);
        request.setAttribute("dimensionalCutDates", dimensionalCutDates);
        request.setAttribute("dimensionalCutDatesData", dimensionalCutDatesData);
        request.setAttribute("pointerScores", pointerScores);
        request.setAttribute("pointerColors", pointerColors);
        request.setAttribute("notes", notes);
        request.setAttribute("noteAttachments", noteAttachments);

        request.setAttribute("rangeDates", rangeDates);
        request.setAttribute("cutMembersString", cutMembersString);

        request.setAttribute("startDate", startDate);
        request.setAttribute("endDate", endDate);

        //Colores
        request.setAttribute("colorimetries", colorimetries);
        request.setAttribute("colorRangeMin", colorRangeMin);
        request.setAttribute("colorRangeMax", colorRangeMax);

        //ActionPlans
        request.setAttribute("actionPlanPojos", actionPlanPojos);

    }
}
